package com.woniu.woniu_bx.utils;

import org.springframework.util.StringUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * <p>处理时间相关的工具类</p>
 * <p>推算动态发布的时间，如：1分钟前、1小时前、昨天、前天......</p>
 * <p>根据出生日期计算当前年龄</p>
 *
 * @author : 王泰元
 * @className: DateUtil
 * @description: TODO
 * @date : 2022/9/3 21:13
 */
public class DateUtil {

    /**
     * 得到动态发布的逻辑时间
     * <p>包括：？秒前、？分钟前、？小时前、昨天、前天、？天前（一周内）、不包括年份日期（一年内）、完整日期......</p>
     *
     * @param dateStr 日期字符串
     * @param format  日期的格式化字符串
     * @return 计算出的时间差
     * @throws ParseException 格式不符规范时抛出该异常
     */
    public static String getLogicTime(String dateStr, String format) throws ParseException {
        // 将字符串转为 Date 日期对象
        Date date = strToDate(dateStr, format);

        // 当前时间毫秒数
        Calendar calendar = Calendar.getInstance();
        calendar.get(Calendar.DAY_OF_MONTH);
        long now = calendar.getTimeInMillis();

        if (calendar.before(date)) {
            throw new IllegalArgumentException("看来这个时间来自未来！");
        }

        // 传入时间毫秒数
        calendar.setTime(date);
        long past = calendar.getTimeInMillis();

        // 相差的秒数
        long timeDiff = (now - past) / 1000;

        StringBuilder sb = new StringBuilder();
        if (timeDiff > 0 && timeDiff < 60) {
            // 一分钟内
            return sb.append(timeDiff).append("秒前").toString();
        } else if (timeDiff < 3600) {
            // 一小时内
            return sb.append(timeDiff / 60).append("分钟前").toString();
        } else if (timeDiff < 3600 * 24) {
            // 一天内
            return sb.append(timeDiff / 3600).append("小时前").toString();
        } else if (timeDiff < 3600 * 24 * 2) {
            // 昨天
            return sb.append("昨天").toString();
        } else if (timeDiff < 3600 * 24 * 3) {
            // 前天
            return sb.append("前天").toString();
        } else if (timeDiff < 3600 * 24 * 7) {
            // 一周内
            return sb.append(timeDiff / 3600 / 24).append("天前").toString();
        } else if (calendar.get(Calendar.YEAR) == Calendar.getInstance().get(Calendar.YEAR)) {
            // 当年，去掉年份
            return new SimpleDateFormat("MM-dd HH:mm:ss").format(date);
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
    }


    /**
     * 根据日期字符串计算年龄
     *
     * @param dateStr 日期字符串
     * @param format  日期格式化字符串
     * @return 年龄 int
     * @throws Exception
     */
    public static int getAge(String dateStr, String format) throws Exception {
        Date birthDay = strToDate(dateStr, format);
        Calendar calendar = Calendar.getInstance();

        // 出生日期晚于当前时间，无法计算
        if (calendar.before(birthDay)) {
            throw new IllegalArgumentException("出生日期晚于当前时间，您是来自未来吗？");
        }

        // 当前年份
        int yearNow = calendar.get(Calendar.YEAR);
        // 当前月份
        int monthNow = calendar.get(Calendar.MONTH);
        // 当前日期
        int dayOfMonthNow = calendar.get(Calendar.DAY_OF_MONTH);

        calendar.setTime(birthDay);
        int yearBirth = calendar.get(Calendar.YEAR);
        int monthBirth = calendar.get(Calendar.MONTH);
        int dayOfMonthBirth = calendar.get(Calendar.DAY_OF_MONTH);
        //计算整岁数
        int age = yearNow - yearBirth;
        if (monthNow <= monthBirth) {
            if (monthNow == monthBirth) {
                //当前日期在生日之前，年龄减一
                if (dayOfMonthNow < dayOfMonthBirth) age--;
            } else {
                //当前月份在生日之前，年龄减一
                age--;
            }
        }
        return age;
    }


    /**
     * 日期字符串转换为Date
     *
     * @param dateStr 日期字符串
     * @param format  日期的格式化字符串
     * @return 计算出的时间差
     * @throws ParseException 格式不符规范时抛出该异常
     */
    private static Date strToDate(String dateStr, String format) throws ParseException {
        Date date;
        if (StringUtils.hasLength(dateStr) && StringUtils.hasLength(format)) {
            DateFormat df = new SimpleDateFormat(format);
            date = df.parse(dateStr);
        } else {
            throw new NullPointerException("日期为空");
        }
        return date;
    }

}